
#include "ncurses.h"
#include "../jncTypeConversion.h"
#include "../jncImportNamespace.h"
#include <panel.h>

class ExpWindow : public JncInterface {
  JNCINTERFACEIMPL(ExpWindow, WINDOW)
    public:
  gReturnCode ConsWindow() {
    return gReturnCode(new WINDOW());
  }
};

class ExpPanel : public JncInterface {
  JNCINTERFACEIMPL(ExpPanel, PANEL)
    public:
  gReturnCode ConsPanel() {
    return gReturnCode(new PANEL());
  }
};

class ExpInitScr : public JncInterface {
 public:
  typedef WINDOW* (*fnInitScr)();
  JNCINTERFACEIMPL(ExpInitScr, fnInitScr)
    public:
  gReturnCode ConsInitScr() {
    return gReturnCode(new WINDOW*(initscr()));
  }
};

class ExpNewWin : public JncInterface {
  typedef WINDOW* (*fnNewWin)(int, int, int, int);
  JNCINTERFACEIMPL(ExpNewWin, fnNewWin)
    public:
  gReturnCode ConsNewWin(jncTypev nl, jncTypev nc, jncTypev y, jncTypev x) {
    return gReturnCode(new WINDOW*(newwin(jint(nl), jint(nc), jint(y), jint(x))));
  }
};

class ExpBox : public JncInterface {
  typedef int (*fnBox)(WINDOW*, chtype, chtype);
  JNCINTERFACEIMPL(ExpBox, fnBox)
    public:
  gReturnCode ConsBox(jncTypev w, jncTypev chv, jncTypev chh) {
    return gReturnCode(new int(box(jcmp<WINDOW*>(w), unjlong(chv), unjlong(chh))));
  }
};

class ExpNewPanel : public JncInterface {
  typedef PANEL* (*fnNewPanel)(WINDOW*);
  JNCINTERFACEIMPL(ExpNewPanel, fnNewPanel)
    public :
  gReturnCode ConsNewPanel(jncTypev w) {
    WINDOW* tmp = jcmp<WINDOW*>(w);
    return gReturnCode(new PANEL*(new_panel(jcmp<WINDOW*>(w))));
  }
};

class ExpUpdatePanel : public JncInterface {
  typedef void (*fnUpdatePanel)();
  JNCINTERFACEIMPL(ExpUpdatePanel, fnUpdatePanel)
    public :
  gReturnCode ConsUpdatePanel() {
    update_panels();
    return gReturnCode();
  }
};

class ExpDoupdate : public JncInterface {
  typedef int (*fnDoupdate)();
  JNCINTERFACEIMPL(ExpDoupdate, fnDoupdate)
    public :
  gReturnCode ConsDoupdate() {
    return gReturnCode(new int(doupdate()));
  }
};

class ExpGetch : public JncInterface {
  typedef int (*fnGetch)();
  JNCINTERFACEIMPL(ExpGetch, fnGetch)
    public :
  gReturnCode ConsGetch() {
    return gReturnCode(new int(getch()));
  }
};

class ExpEndwin : public JncInterface {
  typedef int (*fnEndwin)();
  JNCINTERFACEIMPL(ExpEndwin, fnEndwin);
 public :
  gReturnCode ConsEndwin() {
    return gReturnCode(new int(endwin()));
  }
};


void getNcursesNamespace() {
  static boost::shared_ptr<ExpWindow> ptr_exp_window(new ExpWindow());
  static boost::shared_ptr<ExpPanel> ptr_exp_panel(new ExpPanel());
  static boost::shared_ptr<ExpInitScr> ptr_exp_initscr(new ExpInitScr());
  static boost::shared_ptr<ExpNewWin> ptr_exp_newwin(new ExpNewWin());
  static boost::shared_ptr<ExpBox> ptr_exp_box(new ExpBox());
  static boost::shared_ptr<ExpNewPanel> ptr_exp_newpanel(new ExpNewPanel());
  static boost::shared_ptr<ExpUpdatePanel> ptr_exp_updatepanel(new ExpUpdatePanel());
  static boost::shared_ptr<ExpDoupdate> ptr_exp_doupdate(new ExpDoupdate());
  static boost::shared_ptr<ExpGetch> ptr_exp_getch(new ExpGetch());
  static boost::shared_ptr<ExpEndwin> ptr_exp_endwin(new ExpEndwin());
  exportObjectHandle<ExpWindow>(
				get_pointer(ptr_exp_window),
				(const char* [JINC_MAX_ARG]){"WINDOW", NULL},
				(jncTypei [JINC_MAX_ARG]){JCMP},
				&ExpWindow::ConsWindow,
				NORMAL
				);
  exportObjectHandle<ExpPanel>(
			       get_pointer(ptr_exp_panel),
			       (const char* [JINC_MAX_ARG]){"PANEL", NULL},
			       (jncTypei [JINC_MAX_ARG]){JCMP},
			       &ExpPanel::ConsPanel,
			       NORMAL
			       );
  exportObjectHandle<ExpInitScr>(
				 get_pointer(ptr_exp_initscr),
				 (const char* [JINC_MAX_ARG]){"initscr", NULL},
				 (jncTypei [JINC_MAX_ARG]){JCMP},
				 &ExpInitScr::ConsInitScr,
				 NORMAL
				 );
  exportObjectHandle<ExpNewWin>(
				get_pointer(ptr_exp_newwin),
				(const char* [JINC_MAX_ARG]){"newwin", "lines", "cols", "coordy", "coordx", NULL},
				(jncTypei [JINC_MAX_ARG]){JCMP, JCMP, JCMP, JCMP, JCMP},
				&ExpNewWin::ConsNewWin,
				NORMAL
				);
  exportObjectHandle<ExpBox>(
			     get_pointer(ptr_exp_box),
			     (const char* [JINC_MAX_ARG]){"box", "p_WINDOW", "ver", "hor", NULL},
			     (jncTypei [JINC_MAX_ARG]){JCMP, JCMP, JCMP, JCMP},
			     &ExpBox::ConsBox,
			     LOW
			     );
  exportObjectHandle<ExpNewPanel>(
				  get_pointer(ptr_exp_newpanel),
				  (const char* [JINC_MAX_ARG]){"new_panel", "p_WINDOW", NULL},
				  (jncTypei [JINC_MAX_ARG]){JCMP, JCMP},
				  &ExpNewPanel::ConsNewPanel,
				  LOW
				  );
  exportObjectHandle<ExpUpdatePanel>(
				     get_pointer(ptr_exp_updatepanel),
				     (const char* [JINC_MAX_ARG]){"update_panels", NULL},
				     (jncTypei [JINC_MAX_ARG]){JCMP},
				     &ExpUpdatePanel::ConsUpdatePanel,
				     NORMAL
				     );
  exportObjectHandle<ExpDoupdate>(
				  get_pointer(ptr_exp_doupdate),
				  (const char* [JINC_MAX_ARG]){"doupdate", NULL},
				  (jncTypei [JINC_MAX_ARG]){JCMP},
				  &ExpDoupdate::ConsDoupdate,
				  NORMAL
				  );
  exportObjectHandle<ExpGetch>(
			       get_pointer(ptr_exp_getch),
			       (const char* [JINC_MAX_ARG]){"getch", NULL},
			       (jncTypei [JINC_MAX_ARG]){JCMP},
			       &ExpGetch::ConsGetch,
				NORMAL
			       );
  exportObjectHandle<ExpEndwin>(
				get_pointer(ptr_exp_endwin),
				(const char* [JINC_MAX_ARG]){"endwin", NULL},
				(jncTypei [JINC_MAX_ARG]){JCMP},
				&ExpEndwin::ConsEndwin,
				NORMAL
				);
}
